import os
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from pathlib import Path
import uuid
import shutil
from typing import Optional
from app.config import config
from app.processors import processor
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI(title="人脸和车牌信息遮拦处理系统")

# 挂载静态文件
app.mount("/static", StaticFiles(directory=config.BASE_DIR / "static"), name="static")

@app.on_event("startup")
async def startup_event():
    logger.info("应用启动，初始化完成")

@app.get("/", response_class=HTMLResponse)
async def upload_form():
    """显示上传表单"""
    try:
        with open(Path(__file__).parent.parent / "templates" / "index.html", "r", encoding="utf-8") as f:
            return HTMLResponse(content=f.read(), status_code=200)
    except Exception as e:
        logger.error(f"无法加载模板文件: {e}")
        raise HTTPException(status_code=500, detail="无法加载页面")

@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
    """处理文件上传"""
    try:
        # 检查文件类型
        file_type = "video" if any(file.filename.lower().endswith(ext) for ext in config.ALLOWED_EXTENSIONS["video"]) else "image"
        if not any(file.filename.lower().endswith(ext) for ext in config.ALLOWED_EXTENSIONS["image"] + config.ALLOWED_EXTENSIONS["video"]):
            raise HTTPException(status_code=400, detail="不支持的文件类型")
        
        # 生成唯一文件名
        file_ext = file.filename.split(".")[-1].lower()
        unique_filename = f"{uuid.uuid4().hex}.{file_ext}"
        upload_path = config.UPLOAD_FOLDER / unique_filename
        
        # 保存上传文件
        logger.info(f"保存上传文件到: {upload_path}")
        with open(upload_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        
        # 处理文件
        processed_filename = f"processed_{unique_filename}"
        processed_path = config.PROCESSED_FOLDER / processed_filename
        
        try:
            if file_type == "image":
                processor.process_image(upload_path, processed_path)
            else:
                processor.process_video(upload_path, processed_path)
        except Exception as e:
            logger.error(f"文件处理失败: {e}")
            raise HTTPException(status_code=500, detail=f"文件处理失败: {str(e)}")
        finally:
            # 清理上传的原始文件
            if upload_path.exists():
                os.remove(upload_path)
        
        # 返回下载链接
        return {
            "status": "success",
            "filename": processed_filename,
            "download_url": f"/download/{processed_filename}"
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"上传处理失败: {e}")
        raise HTTPException(status_code=500, detail=f"服务器错误: {str(e)}")

@app.get("/download/{filename}")
async def download_file(filename: str):
    """提供文件下载"""
    file_path = config.PROCESSED_FOLDER / filename
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="文件未找到")
    
    return FileResponse(
        file_path,
        filename=filename,
        media_type="application/octet-stream"
    )

@app.on_event("shutdown")
async def cleanup():
    """应用关闭时清理临时文件"""
    logger.info("清理临时文件...")
    for folder in [config.UPLOAD_FOLDER, config.PROCESSED_FOLDER]:
        for file in folder.glob("*"):
            try:
                if file.is_file():
                    file.unlink()
            except Exception as e:
                logger.error(f"清理文件失败 {file}: {e}")